// 有类型参数的地方就有约束(X extends ...)
// 约束有两重含义:
// - 1.推断的限制
// - 2.推断的结果类型

// 示例: 使用递归来列举字符串和元组
type ReverseString<T> = T extends string
    ? ReverseString<[T, ""]>
        : T extends [infer T2, infer Result extends string]
            ? T2 extends `${infer C}${infer X}`
                ? ReverseString<[X, `${C}${Result}`]>
                : Result
            : never

type T8 = ReverseString<'abcd'> // 'dcba'
type T81 = ReverseString<['abcd', '']> // 'dcba'
type T82 = "" extends `${infer C}${infer X}` ? [C, X] : never
type T83 = ReverseString<""> // ""
type T84 = ReverseString<never> // WARNNING: 在第一行检测时即返回
type T85 = ReverseString<any> // ERROR: 类型any不能分配给类型string 


// 简化版
type ReverseString1<T extends string, R extends string = ''> = 
    T extends `${infer L}${infer Rest}`
        ? ReverseString1<Rest, `${L}${R}`>
        : R

type T1 = ReverseString1<'hello'> // 'olleh'
type T2 = ReverseString1<never> // never
type T3 = ReverseString1<any> // 






// 约束的语义1: "必须是": 限制推断类型(参数传入限制)
type X6 = {
    a: string
    b: 1,
    c: 1,
    d: {
        1: string,
        a: number
    }
}
type T6 = X6 extends {a: infer x; d: infer y extends object} ? [x, y]: never


// 约束的语义2: "将会是": 结果的类型
type T71 = 'a11.234true1234abcd' extends
// 注意: ${infer x extends `1${infer y}`} 是嵌套推断, 官方并没有明确定义, 结果不可靠
    `a${infer x extends `1${infer y}`}true${string}`
    ? [x, y]
    : never // ["11.234", string]
type T72 =  'a423true11111c' extends `a${infer L}${infer X extends number}${true}${infer R}c`
    ? [L, X, R]
    : never // ["4", 23, "11111"]

// 取枚举中的数字值(联合)
enum T { A, B, C, D, E='abc', F=5, G='def'} // 
type T61 = `${Extract<T, number>}` extends `${infer N extends number}` ? N: never // 0 | 1 | 2 | 3 | 5

// 取枚举中的字符串值(联合)
type T62 = `${Extract<T, string>}` extends `${infer S}` ? S: never // "abc" | "def"
